import time
import gradio as gr
from dotenv import load_dotenv
import chat_service
import knowledge_base_service
import utils
from langchain_community.embeddings import DashScopeEmbeddings

load_dotenv("config/key.env")

css="""
 #component-23{
    
    border:0;
    padding:0;
    
    
    
    }
@media (max-width: 600px) { /* 当窗口宽度小于600px时 */
            #component-25 {
               display: none; /* 隐藏左右两边的项 */
           }

           #component-30 {
              flex: 1 1 100%; /* 让中间项占据全部可用空间 */
            }
       }     
"""
with gr.Blocks(theme="soft", title="私有知识库问答系统",css=css) as demo:
    gr.HTML("<h1 style='text-align:center'>本地知识库问答系统<h1>")
    with gr.Tab("知识库管理"):
        with gr.Row():
            with gr.Column(scale=2):
                # df_knowledge_base = gr.Dataframe(headers=["知识库"],
                #
                #                                 datatype=["str"], value=knowledge_base_service.get_knowledge_list())
                pass
            with gr.Column(scale=8):
                with gr.Row():
                    with gr.Column(6):
                        file_display_knowledge_base_file = gr.File(file_count="multiple", interactive=False)

                    with gr.Column(2):
                        btn_delete_knowledge_base = gr.Button("删除知识库", min_width=1)
                        btn_delete_knowledge_base_file = gr.Button("删除文件", min_width=1)
                        btn_download_knowledge_base_file = gr.Button("下载文件", min_width=1)
                        btn_add_knowledge_base_file = gr.Button("添加文件", min_width=1)
                        file_upload_knowledge_base_file = gr.File(file_count="multiple")
        with gr.Column():
            with gr.Row():
                ddKnowSelect1 = gr.Dropdown(choices=knowledge_base_service.get_knowledge(), label="选择知识库")
                txtKnowSelect1 = gr.Textbox(label="知识库名")
                btnCJZSK = gr.Button("创建知识库", variant="secondary", size="sm")
        with gr.Column():
            uplodafile1 = gr.File(file_count="multiple")

    with gr.Tab("对话"):
        with gr.Row():
            with gr.Column(scale=1):
                # 模型选择
                ddModuleSelect = gr.Dropdown(choices=utils.getAllModels(), value="qwen-turbo", label="选择模型")
                chatMode = gr.Radio(["大模型", "大模型+知识库", "大模型+代理"], value="大模型", label="对话模式")

                ddKnowSelect = gr.Dropdown(choices=knowledge_base_service.get_knowledge(), label="选择知识库")

            with gr.Column(scale=4):
                with gr.Row():
                    chatbot = gr.Chatbot(scale=10, label="对话框",height=680,avatar_images=("web_assets/user.png","web_assets/chatbot.png") )
                with gr.Row():
                    txtUserMsg = gr.Textbox(show_label=False, placeholder="请输入你的问题", scale=8, lines=4)
                    btnSendUserMsg = gr.Button("发送", variant="secondary", size="sm", min_width=1, scale=1)
                    btnStop = gr.Button("中断", variant="secondary", size="sm", min_width=1, scale=1)
                with gr.Row():
                    btnRetry = gr.Button("🔄  重发", variant="secondary", size="sm")
                    btnUndo = gr.Button("↩️撤销", variant="secondary", size="sm")
                    btnClear = gr.ClearButton([txtUserMsg, chatbot])


        def respond(message: str, chatHistory):
            return "", chatHistory + [[message, None]]


        def handle_message(chat_history, model_name: str, chat_mode: str, know):
            chat_history[-1][1] = ""
            result = chat_service.handle_message(chat_history, model_name, chat_mode, know)
            for character in result:
                chat_history[-1][1] += character
                time.sleep(0.09)
                yield chat_history


        def undo(chat_history):
            """
        撤回最近一条消息
        :param chat_history:
        :return:
        """
            if len(chat_history) == 0:
                return []
            del chat_history[-1]
            return chat_history


        def filehandler(file, knowledge_name):

            knowledge_base_service.create_knowledge_base_data(knowledge_name, file, DashScopeEmbeddings())
            gr.Info("知识库生成成功", )


        def updateValue():
            return gr.update(choices=knowledge_base_service.get_knowledge())


        def updateDfValue():
            return gr.update(value=knowledge_base_service.get_knowledge_list())


        def login(username, password):

            gr.State()

            if username == "hehao" and password == "0428":
                return True
            return False


        def Stop():
            return True


        def load_knowledge_base_file(evt: gr.SelectData):

            return knowledge_base_service.get_knowledge_base_file(evt.value, DashScopeEmbeddings())


        def delete_knowledge_base_file(evt: gr.EventData):

            return knowledge_base_service.get_knowledge_base_file(evt, DashScopeEmbeddings())


        submit_event = btnSendUserMsg.click(respond, [txtUserMsg, chatbot], [txtUserMsg, chatbot], queue=False, ).then(
            handle_message, [chatbot, ddModuleSelect, chatMode, ddKnowSelect], chatbot, queue=True,
            concurrency_limit=100)

        btnRetry.click(handle_message, [chatbot, ddModuleSelect, chatMode, ddKnowSelect], [chatbot], queue=True,
                       concurrency_limit=100)
        btnUndo.click(undo, [chatbot], [chatbot], queue=True, concurrency_limit=100)
        btnCJZSK.click(filehandler, [uplodafile1, txtKnowSelect1], queue=True,
                       concurrency_limit=100)

        # btnStop.click(stop, None, None, cancels={"a": bot})

        # df_knowledge_base.select(load_knowledge_base_file, None, file_display_knowledge_base_file)

        file_display_knowledge_base_file.change(delete_knowledge_base_file, None, None)
        btnStop.click(None, None, None, cancels=[submit_event])

        # demo.load(updateValue, None, [ddKnowSelect])
        # demo.load(updateDfValue, None, [df_knowledge_base])

demo.queue()
app, a, b = demo.launch(share=True)
